home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-30 | 27.3 KB | 1,102 lines | [TEXT/MPS ] |
- /*
- File: ADSPSample.cp
-
- Contains: Sample program for the ADSP endpoint
-
- Copyright: © 1992-1995 by Apple Computer, Inc., all rights reserved.
-
- */
-
- //
- // We want to use the OT 'new' operator, not the standard MPW one, so include
- // OpenTptGlobalNew.h first. This is because we use it at Interrupt time.
- //
- #ifndef __OPENTPTGLOBALNEW__
- #include <OpenTptGlobalNew.h>
- #endif
- #ifndef __OPENTPTAPPLETALK__
- #include <OpenTptAppleTalk.h>
- #endif
- #ifndef __ATALKSAMPLEUTILS__
- #include "ATalkSampleUtils.h"
- #endif
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
- #ifndef __EVENTS__
- #include <Events.h>
- #endif
-
- const size_t kMaxEndpoints = 3;
-
- #define USENBPBIND 1
-
- /*******************************************************************************
- ** Structures
- ********************************************************************************/
-
- class TOTEventItem
- {
- public:
- inline TOTEventItem(void* ref, unsigned long code,
- OTResult result, void* cookie)
- {
- fLink.fNext = NULL;
- fRef = ref;
- fCode = code;
- fResult = result;
- fCookie = cookie;
- };
- OTLink fLink;
- void* fRef;
- unsigned long fCode;
- OTResult fResult;
- void* fCookie;
- };
-
- struct TTIIEventList
- {
- TOTEventItem* fHead;
- TOTEventItem* fTail;
- };
-
- /*******************************************************************************
- ** GlobalVariables
- ********************************************************************************/
-
- OTLIFO gEventList = { 0 };
- TEndpoint* gEp[kMaxEndpoints] = {NULL, NULL, NULL};
-
- Boolean gDoingTearDown = false;
-
- const UInt16 kDoBindFlag = 0x0001;
- const UInt16 kDoConnectFlag = 0x0002;
- const UInt16 kDoListenFlag = 0x0004;
- const UInt16 kDoAcceptFlag = 0x0008;
- const UInt16 kDoRejectFlag = 0x0010;
- const UInt16 kDoHandOffFlag = 0x0020;
- const UInt16 kDoSelfSend = 0x0040;
- const UInt16 kDoProtAddrAfterConnect = 0x0080;
- const UInt16 kDoProtAddrAfterBind = 0x0100;
- const UInt16 kSendFlowedFlag = 0x0200;
- const UInt16 kSendExFlowedFlag = 0x0400;
-
- UInt16 gEpFlags[kMaxEndpoints] = {0, 0, 0};
- OTResult gEpStates[kMaxEndpoints] = {-1, -1, -1};
-
- DDPAddress gAddr[2*kMaxEndpoints]; // Who they connect to
-
- UInt8 gSendBuf[200];
-
- int gTestNum;
-
- UInt32 gByteCtr;
- UInt16 gDotCtr;
- const UInt32 kBytesPerDot = 10000;
- const UInt16 kDotsPerLine = 64;
-
- /*******************************************************************************
- ** Universal event handler...
- ********************************************************************************/
-
- pascal void UniversalEventHandler(void* contextPtr, OTEventCode code,
- OTResult result, void* cookie)
- {
- TOTEventItem* item = new TOTEventItem(contextPtr, code, result, cookie);
- if ( item == NULL )
- {
- DebugStr("\pADSPSample: UniversalEventHandler -- could not allocate event structure");
- }
- else
- {
- OTLIFOEnqueue(&gEventList, &item->fLink); /* Atomically add to list */
- }
- }
-
- /*******************************************************************************
- ** DoSend
- ********************************************************************************/
-
- static char gTheData[] = "\x01Hello. This is a test of the emergency broadcast system.";
-
- OSStatus DoSend(int epNum, Boolean expedited, Boolean more)
- {
- TEndpoint* ep = gEp[epNum];
-
- //
- // If we think we're flowed, don't send anything
- //
- if ( gEpFlags[epNum] & (expedited ? kSendExFlowedFlag : kSendFlowedFlag) )
- return 0;
-
-
- gTheData[0] += 1;
-
- OTResult result = ep->Snd(gTheData, sizeof(gTheData),
- ((expedited ? T_EXPEDITED : 0 ) | (more ? T_MORE : 0)));
-
- if ( result == kOTFlowErr )
- {
- fprintf(stderr, "Snd(%d) flow controlled on %s channel\n", epNum,
- expedited ? "EXPEDITED" : "NORMAL");
- gEpFlags[epNum] |= expedited ? kSendExFlowedFlag : kSendFlowedFlag;
- return kOTNoError;
- }
-
- if ( result == kOTLookErr || result == kOTOutStateErr )
- return kOTNoError;
-
- if ( result < 0 )
- {
- fprintf(stderr, "Snd(%d) fails with %d\n", epNum, result);
- }
- else
- result = kOTNoError;
- return (OSStatus)result;
- }
-
- /*******************************************************************************
- ** DoRead
- **
- ** Returns kOTNoDataErr if there no data
- ********************************************************************************/
-
- OSStatus DoRead(int epNum)
- {
- TEndpoint* ep = gEp[epNum];
- OTFlags flags = 0;
- UInt8 buf[200];
- OTResult result;
-
- while (true)
- {
- result = ep->Rcv(buf, sizeof(buf), &flags);
- if ( result == kOTNoDataErr )
- return kOTNoDataErr;
- if ( result == kOTNoDataErr || result == kOTLookErr ||
- result == kOTOutStateErr )
- return kOTNoError;
-
- if ( result < 0 )
- {
- fprintf(stderr, "Rcv(%d) fails with %d\n", epNum, result);
- return result;
- }
-
- #if 0
- fprintf(stderr, "Rcv(%d): flags=%08lX; #%d bytes: ", epNum, flags, result);
- if ( result > 10 )
- result = 10;
-
- for ( OTResult i = 0 ; i < result ; i++ )
- fprintf(stderr, "%02x ", buf[i]);
- fprintf(stderr, "\n");
- #else
- gByteCtr += result;
- if ( gByteCtr >= kBytesPerDot )
- {
- gByteCtr -= kBytesPerDot;
- putc('.', stderr);
- if (++gDotCtr >= kDotsPerLine )
- {
- putc('\n', stderr);
- gDotCtr = 0;
- }
- fflush(stderr);
- }
-
- #endif
- }
-
- return kOTNoError;
- }
-
- #if USENBPBIND
- /*******************************************************************************
- ** DoBind
- ********************************************************************************/
-
- OSStatus DoBind(int epNum, int qlen)
- {
- char namebuf[64];
- TEndpoint* ep = gEp[epNum];
- OSStatus err;
- DDPNBPAddress myAddress; // To set up my address for the bind
-
- TBind* retBind = new TBind;
-
- if ( retBind == NULL )
- {
- DebugStr("\pADSPSample: DoBind, can not allocate TBind.");
- return -1;
- }
-
- sprintf(namebuf, "Test%d%d:ADSPSample", gTestNum, epNum);
- //
- // Initialize my address
- //
- myAddress.Init(0, 0, 0); // Source address & type
- //
- // Create the TBind for the request, holding my address
- //
- TBind reqBind;
- //
- // Set my name into the NBP address, and init the TBind with
- // the address (SetNBPEntity returns the size of the address).
- //
- reqBind.addr.buf = (UInt8*)&myAddress;
- reqBind.addr.len = myAddress.SetNBPEntity(namebuf);
- reqBind.qlen = qlen;
-
-
- retBind->addr.buf = (UInt8*)&gAddr[epNum];
- retBind->addr.maxlen = sizeof(gAddr[epNum]);
-
- fprintf(stderr, "Issuing Bind(%d)\n", epNum);
- err = ep->Bind(&reqBind, retBind);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "Bind(%d) fails with %d\n", epNum, err);
- delete retBind;
- }
- return err;
- }
-
- #else
- /*******************************************************************************
- ** DoBind
- ********************************************************************************/
-
- OSStatus DoBind(int epNum, int qlen)
- {
- TEndpoint* ep = gEp[epNum];
- OSStatus err;
- TBind* retBind = new TBind;
-
- if ( retBind == NULL )
- {
- DebugStr("\pADSPSample: DoBind, can not allocate TBind.");
- return -1;
- }
- TBind reqBind;
-
- reqBind.addr.len = 0;
- reqBind.qlen = qlen;
-
- retBind->addr.buf = (UInt8*)&gAddr[epNum];
- retBind->addr.maxlen = sizeof(gAddr[epNum]);
-
- fprintf(stderr, "Issuing Bind(%d)\n", epNum);
- err = ep->Bind(&reqBind, retBind);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "Bind(%d) fails with %d\n", epNum, err);
- delete retBind;
- }
- return err;
- }
- #endif
- /*******************************************************************************
- ** DoConnect
- ********************************************************************************/
-
- OSStatus DoConnect(int epNum, DDPAddress* dest)
- {
- TEndpoint* ep = gEp[epNum];
- //
- // Allocate memory to hold a TCall structure and full ddp addresses
- //
- UInt8* p = new UInt8[sizeof(TCall) + kDDPAddressLength];
-
- TCall* reqCall = (TCall*)p;
-
- reqCall->addr.buf = (UInt8*)(p + sizeof(TCall));
- reqCall->addr.len = kDDPAddressLength;
- reqCall->opt.len = 0;
- reqCall->udata.len = 0;
-
- if ( dest == NULL ) // Need to ask about address
- {
- int net, node, socket;
-
- do
- {
- fprintf(stderr, "Enter the target address in Hex (net node socket):\n");
- scanf("%x %x %x", &net, &node, &socket);
- } while ( socket <= 0 || socket >= 256 || node <= 0 || node >= 256 );
-
- fprintf(stderr, "Connecting to net $%04X, node $%02X, socket $%02X\n",
- net, node, socket);
- ((DDPAddress*)reqCall->addr.buf)->
- Init((UInt16)net, (UInt8)node, (UInt8)socket);
- }
- else
- {
- ((DDPAddress*)reqCall->addr.buf)->Init(*dest);
- }
-
- fprintf(stderr, "Issuing Connect(%d)\n", epNum);
- OSStatus err = ep->Connect(reqCall, NULL);
-
- if ( err != kOTNoDataErr )
- {
- fprintf(stderr, "Connect(%d) returns %d instead of kOTNoDataErr\n", epNum, err);
- delete p;
- return -1;
- }
- return kOTNoError;
- }
-
- /*******************************************************************************
- ** DoListen
- ********************************************************************************/
-
- OSStatus DoListen(int epNum)
- {
- TEndpoint* ep = gEp[epNum];
- OSStatus err = kOTNoError;
- TCall lCall;
-
- lCall.addr.buf = (UInt8*)&gAddr[epNum + kMaxEndpoints];
- lCall.addr.maxlen = sizeof(gAddr[0]);
- lCall.opt.maxlen = 0;
- lCall.udata.maxlen = 0;
-
- err = ep->Listen(&lCall);
- if ( err == kOTNoDataErr || err == kOTStateChangeErr )
- return kOTNoError;
-
- if ( err < 0 )
- {
- fprintf(stderr, "Listen(%d) failed with %d\n", epNum, err);
- return err;
- }
-
- fprintf(stderr, "Listen(%d) received request from ", epNum);
- ShowDDPAddress(&gAddr[epNum + kMaxEndpoints]);
- fprintf(stderr, "\n");
-
- if ( gEpFlags[epNum] & (kDoAcceptFlag | kDoHandOffFlag) )
- {
- Boolean handOff = ( 0!= (gEpFlags[epNum] & kDoHandOffFlag));
- TCall* call = new TCall;
-
- if ( call == NULL )
- return kOTNoError;
- gEpFlags[epNum] &= ~(kDoAcceptFlag | kDoHandOffFlag); // To prevent doing it again
- call->opt.len = 0;
- call->udata.len = 0;
- call->addr.len = 0;
- call->sequence = lCall.sequence;
- int acceptNum = handOff ? 2 : epNum;
- fprintf(stderr, "Issuing Accept(%d) to accept connection\n", acceptNum);
-
- err = ep->Accept(gEp[acceptNum], call);
- if (err)
- {
- fprintf(stderr, "Accept(%d) fails with %d\n", acceptNum, err);
- delete call;
- }
- }
- else if ( gEpFlags[epNum] & kDoRejectFlag )
- {
- gEpFlags[epNum] &= ~kDoRejectFlag; // To prevent doing it again
- fprintf(stderr, "Issuing SndDisconnect(%d) to reject connection\n", epNum);
- err = ep->SndDisconnect(&lCall);
- if ( err != kOTNoError )
- fprintf(stderr, "SndDisconnect(%d) fails with %d\n", epNum, err);
- }
- return err;
- }
-
- /*******************************************************************************
- ** DoGetProtAddr
- ********************************************************************************/
-
- OSStatus DoGetProtAddr(int epNum)
- {
- TEndpoint* ep = gEp[epNum];
- UInt8* p = new UInt8[2 * (sizeof(TBind) + kDDPAddressLength)];
-
- TBind* remBind = (TBind*)p;
- TBind* locBind = (TBind*)(p + sizeof(TBind) + kDDPAddressLength);
-
- remBind->addr.buf = p + sizeof(TBind);
- remBind->addr.maxlen = kDDPAddressLength;
-
- locBind->addr.buf = p + sizeof(TBind) * 2 + kDDPAddressLength;
- locBind->addr.maxlen = kDDPAddressLength;
-
- fprintf(stderr, "Issuing GetProtAddress(%d)\n", epNum);
-
- OSStatus err = ep->GetProtAddress(locBind, remBind);
-
- if ( err == kOTNotSupportedErr )
- {
- fprintf(stderr, "GetProtAddress(%d) is not supported!\n", epNum);
- err = kOTNoError;
- }
- else if ( err != kOTNoError )
- {
- fprintf(stderr, "GetProtAddress(%d) failed with %d\n", epNum, err);
- delete p;
- }
- return err;
- }
-
- /*******************************************************************************
- ** CreateEndpoint
- ********************************************************************************/
-
- TEndpoint* CreateEndpoint(OSStatus* errP, int refNum)
- {
- TEndpoint* ep;
-
- ep = OTOpenEndpoint(OTCreateConfiguration(kADSPName), 0, NULL, errP);
-
- if ( ep == NULL || *errP != kOTNoError )
- {
- fprintf(stderr,"ERROR: open of ADSP Endpoint failed.\n");
- return NULL;
- }
-
- do
- {
- ep->SetSynchronous();
- //
- // Install notifier we're going to use for testing
- //
- *errP = ep->InstallNotifier(&UniversalEventHandler, (void*)(refNum+1));
- if ( *errP != kOTNoError )
- {
- fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", *errP);
- break;
- }
- //
- // Have to do this until the autopush stuff works right.
- //
- ep->Sync();
- return ep;
-
- } while (false);
-
- if ( ep != NULL )
- ep->Close();
-
- return NULL;
- }
-
- /*******************************************************************************
- ** CheckEndpointState
- ********************************************************************************/
-
- OSStatus CheckEndpointState(int epNum)
- {
- OSStatus err = kOTNoError;
- TEndpoint* ep = gEp[epNum];
- UInt16 flags = gEpFlags[epNum];
-
- OTResult state = ep->GetEndpointState();
-
- //
- // Hmm. Things in progress. They will eventually complete.
- //
- if ( state == kOTStateChangeErr )
- return kOTNoError;
-
- if ( state < 0 ) // Got an error from GetEndpoint State
- {
- fprintf(stderr, "GetEndpointState(%d) fails with %d\n", epNum, state);
- return state;
- }
-
- if ( state != gEpStates[epNum] ) // Detected state change.
- {
- gEpStates[epNum] = state;
- fprintf(stderr, "State change on endpoint #%d to ", epNum);
- ShowEndpointState(ep, "");
- }
-
- //
- // Based on the current state, we may want to do something...
- //
- switch ( state )
- {
- case T_UNBND:
- if ( flags & kDoBindFlag )
- {
- gEpFlags[epNum] &= ~kDoBindFlag; // To prevent doing it again
- return DoBind(epNum, (epNum == 1) ? 1 : 0);
- }
- break;
-
- case T_IDLE:
- if ( gDoingTearDown )
- {
- fprintf(stderr, "Issuing Unbind(%d)\n", epNum);
- err = ep->Unbind();
- if ( err == kOTStateChangeErr || err == kOTOutStateErr )
- err = kOTNoError;
- else if ( err != kOTNoError )
- fprintf(stderr, "Unbind(%d) fails with %d\n", epNum, err);
- }
- else if ( flags & kDoProtAddrAfterBind )
- {
- gEpFlags[epNum] &= ~kDoProtAddrAfterBind; // To prevent doing it again
- err = DoGetProtAddr(epNum);
- }
- else
- {
- if ( flags & kDoConnectFlag )
- {
- gEpFlags[epNum] &= ~kDoConnectFlag; // To prevent doing it again
- if ( gEpFlags[epNum] & kDoSelfSend )
- err = DoConnect(epNum, &gAddr[epNum + 1]);
- else
- err = DoConnect(epNum, NULL);
- }
- }
- break;
-
- case T_OUTCON:
- break;
-
- case T_INCON:
- break;
-
- case T_DATAXFER:
- if ( gDoingTearDown )
- {
- fprintf(stderr, "Issuing SndOrderlyDisconnect(%d)\n", epNum);
- err = ep->SndOrderlyDisconnect();
- if (err != kOTNoError )
- {
- if ( err == kOTLookErr )
- {
- fprintf(stderr,
- "SndOrderlyDisconnect(%d) returns with kLook\n", epNum);
- err = kOTNoError;
- }
- else
- fprintf(stderr,
- "SndOrderlyDisconnect(%d) fails with %d\n", epNum, err);
- }
- }
- else if ( flags & kDoProtAddrAfterConnect )
- {
- gEpFlags[epNum] &= ~kDoProtAddrAfterConnect; // To prevent doing it again
- err = DoGetProtAddr(epNum);
- }
- else
- {
- err = DoRead(epNum);
- #if 1
- if ( err == kOTNoDataErr ) // Only send if we read nothing
- err = DoSend(epNum, false, false);
- #else
- if ( err == kOTNoDataErr || err == kOTLookErr )
- err = kOTNoError;
- #endif
- }
- break;
-
- case T_UNINIT:
- fprintf(stderr,
- "GetEndpointState(%d) returns unexpected state T_UNINIT\n", epNum);
- err = -1;
-
- case T_OUTREL: // We're waiting for a T_ORDREL event coming in.
- // Must continue to read any incoming data
- err = DoRead(epNum);
- if ( err == kOTNoDataErr || err == kOTLookErr )
- err = kOTNoError;
- break;
-
- case T_INREL:
- fprintf(stderr, "Issuing SndOrderlyDisconnect(%d)\n", epNum);
- err = ep->SndOrderlyDisconnect();
- if ( err != kOTNoError )
- {
- if ( err == kOTLookErr )
- {
- fprintf(stderr,
- "SndOrderlyDisconnect(%d) returns with kOTLookErr\n", epNum);
- err = kOTNoError;
- }
- else
- fprintf(stderr,
- "SndOrderlyDisconnect(%d) fails with %d\n", epNum, err);
- }
- break;
-
- default:
- fprintf(stderr,
- "GetEndpointState(%d) returns unknown state %d\n", epNum, state);
- err = -1;
- break;
- };
-
- return err;
- }
-
- /*******************************************************************************
- ** PollEventList
- ********************************************************************************/
-
- OSStatus PollEventList()
- {
- OSStatus err = kOTNoError;
-
- while ( gEventList.fHead != NULL )
- {
- OTLink* link = OTReverseList(OTLIFOStealList(&gEventList));
-
- while ( link != NULL )
- {
- TOTEventItem* item = OTGetLinkObject(link, TOTEventItem, fLink);
- OTResult result = item->fResult;
- void* cookie = item->fCookie;
- int epNum = (int)item->fRef - 1;
-
- link = link->fNext;
-
- if ( epNum < 0 || epNum > 2 )
- {
- delete item;
- continue;
- }
-
- TEndpoint* ep = gEp[epNum];
-
- switch ( item->fCode )
- {
- case T_BINDCOMPLETE:
- {
- TBind* bindRet = (TBind*)item->fCookie;
- if ( result != kOTNoError )
- {
- fprintf(stderr, "Bind(%d) failed with %d\n", epNum, result);
- err = (OSStatus)result;
- }
- else
- {
- fprintf(stderr, "Endpoint #%d bound to ", epNum);
- ShowDDPAddress(&gAddr[epNum]);
- fprintf(stderr, "\n");
- }
- delete bindRet;
- break;
- }
-
- case T_UNBINDCOMPLETE:
- if (result != kOTNoError )
- {
- fprintf(stderr, "Unbind(%d) failed with %d\n", epNum, result);
- err = 0; // Ignore errors from unbind
- }
- break;
-
- case T_DISCONNECT:
- {
- fprintf(stderr, "T_DISCONNECT event on endpoint #%d\n", epNum);
- TBind* bindReq = (TBind*)item->fCookie;
-
- if ( bindReq != NULL ) // A connect is rejected
- {
- fprintf(stderr, "Connect(%d) rejected\n", epNum);
- }
- fprintf(stderr, "Issuing RcvDisconnect(%d)\n", epNum);
- err = ep->RcvDisconnect(NULL);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "RcvDisconnect(%d) fails with %d\n", epNum, err);
- }
- break;
- }
-
- case T_ORDREL:
- {
- fprintf(stderr, "T_ORDREL event on endpoint #%d\n", epNum);
- fprintf(stderr, "Issuing RcvOrderlyDisconnect(%d)\n", epNum);
- err = ep->RcvOrderlyDisconnect();
- if ( err != kOTNoError )
- {
- fprintf(stderr, "RcvOrderlyDisconnect(%d) fails with %d\n", epNum, err);
- }
- break;
- }
-
- case T_CONNECT:
- {
- TCall* reqCall = (TCall*)item->fCookie;
- delete reqCall;
-
- if ( result != kOTNoError )
- {
- fprintf(stderr, "Connect(%d) failed with %d\n", epNum, result);
- err = (OSStatus)result;
- }
- else
- {
- TCall retCall;
-
- retCall.addr.buf = (UInt8*)&gAddr[epNum + kMaxEndpoints];
- retCall.addr.maxlen = kDDPAddressLength;
- retCall.opt.len = 0;
- retCall.opt.maxlen = 0;
- retCall.udata.len = 0;
- retCall.udata.maxlen = 0;
-
- fprintf(stderr, "Connect(%d) completes with no error\n", epNum);
- fprintf(stderr, "Issuing RcvConnect(%d)\n", epNum);
- err = ep->RcvConnect(&retCall);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "RcvConnect(%d) fails with %d\n", epNum, err);
- }
- else
- {
- fprintf(stderr, "Endpoint #%d connected to ", epNum);
- ShowDDPAddress(&gAddr[epNum + kMaxEndpoints]);
- fprintf(stderr, "\n");
- }
- }
- break;
- }
-
- case T_ACCEPTCOMPLETE:
- {
- if ( result == kOTNoError )
- fprintf(stderr, "Accept(%d) completes with no error\n", epNum);
- else
- {
- fprintf(stderr, "Accept(%d) fails with %d\n", epNum, result);
- err = (OSStatus)result;
- }
- break;
- }
-
- case T_PASSCON:
- fprintf(stderr, "T_PASSCON event on Ep #%d\n", epNum);
- break;
-
- case T_GETPROTADDRCOMPLETE:
- {
- TBind* remBind = (TBind*)item->fCookie;
- TBind* locBind = (TBind*)((UInt8*)remBind +
- sizeof(TBind) + kDDPAddressLength);
-
- if ( result == kOTNoError )
- {
- fprintf(stderr, "GetProtAddress(%d) completes with no error\n", epNum);
- fprintf(stderr, " LocAddr = ");
- ShowDDPAddress((DDPAddress*)locBind->addr.buf);
- fprintf(stderr, "\n");
- fprintf(stderr, " RemAddr = ");
- ShowDDPAddress((DDPAddress*)remBind->addr.buf);
- fprintf(stderr, "\n");
- //
- // Save our local address in global array
- //
- gAddr[epNum].Init(*(DDPAddress*)locBind->addr.buf);
- }
- else if ( result == kOTNotSupportedErr )
- {
- fprintf(stderr, "GetProtAddress(%d) is not supported!\n", epNum, result);
- err = kOTNoError;
- }
- else
- {
- fprintf(stderr, "GetProtAddress(%d) fails with %d\n", epNum, result);
- err = (OSStatus)result;
- }
- delete remBind;
- break;
- }
-
- case T_DISCONNECTCOMPLETE:
- {
- TDiscon* discon = (TDiscon*)item->fCookie;
-
- if ( result == kOTNoError )
- {
- fprintf(stderr, "SndDisconnect(%d) completes with no error\n", epNum);
- }
- else
- {
- fprintf(stderr, "SndDisconnect(%d) fails with %d\n", epNum, result);
- err = (OSStatus)result;
- }
- delete discon;
- break;
- }
-
- case T_LISTEN:
- {
- err = DoListen(epNum);
- break;
- }
-
- case T_DATA:
- //fprintf(stderr, "T_DATA event on Ep #%d\n", epNum);
- // Fall into next case
-
- case T_EXDATA:
- if ( item->fCode == T_EXDATA )
- fprintf(stderr, "T_EXDATA event on Ep #%d\n", epNum);
- break;
-
- case T_GODATA:
- gEpFlags[epNum] &= ~kSendFlowedFlag;
- fprintf(stderr, "GoData event on Ep #%d\n", epNum);
- break;
-
- case T_GOEXDATA:
- gEpFlags[epNum] &= ~kSendExFlowedFlag;
- fprintf(stderr, "GoExData event on Ep #%d\n", epNum);
- break;
-
- default:
- fprintf(stderr, "Unknown event in event record, %08LX\n", item->fCode);
- break;
- }
- delete item;
- }
- }
- return err;
- }
-
- /*******************************************************************************
- ** DoTest
- ********************************************************************************/
-
- void DoTest()
- {
- OSStatus err = kOTNoError;
- TEndpoint* ep = NULL;
- Boolean quit = false;
-
- gByteCtr = 0;
- gDotCtr = 0;
-
- int epNum;
-
- //
- // Initialize address variables
- //
- for ( epNum = 0 ; epNum < (2 * kMaxEndpoints) ; epNum++ )
- {
- gAddr[epNum].Init(0, 0, 0);
- }
-
- do
- {
- //
- // Create the endpoints
- //
- for ( epNum = 0 ; epNum < kMaxEndpoints ; epNum++ )
- {
- gEp[epNum] = CreateEndpoint(&err, epNum);
- if ( gEp[epNum] == NULL || err != kOTNoError )
- break;
- gEp[epNum]->SetAsynchronous(); // Ensure endpoint is async
- gEp[epNum]->SetNonBlocking(); // Ensure endpoint is non-blocking
- }
- if ( err != kOTNoError )
- break;
-
- //
- // Dump out the Endpoint Info for one of the endpoints.
- // Must set it in synchronous mode first, because we want to print out
- // the results.
- //
- gEp[0]->SetSynchronous();
- ShowFullEndpointData(gEp[0]);
- gEp[0]->SetAsynchronous();
-
- //
- // Ask user what to do
- //
- gTestNum = -2;
-
- while ( gTestNum < 0 || gTestNum > 7 )
- {
- fprintf(stderr, "\nChoose Test:\n");
- fprintf(stderr, " 0) QUIT, QUIT, QUIT\n");
- fprintf(stderr, " 1) Connect to remote node\n");
- fprintf(stderr, " 2) Listen and accept connection from remote node\n");
- fprintf(stderr, " 3) Listen and reject connection from remote node\n");
- fprintf(stderr, " 4) Listen and handoff connection from remote node\n");
- fprintf(stderr, " 5) Connect/Listen/Accept self-send\n");
- fprintf(stderr, " 6) Connect/Listen/Reject self-send\n");
- fprintf(stderr, " 7) Connect/Listen/handoff self-send\n");
- scanf("%x", &gTestNum);
- }
-
- //
- // Set a bunch of flags so that the various other parts of the program
- // know what to do.
- //
- switch ( gTestNum )
- {
- case 0: // Quit
- quit = true;
- break;
-
- case 1: // Connect to remote node
- gEpFlags[0] = kDoBindFlag | kDoProtAddrAfterBind |
- kDoConnectFlag | kDoProtAddrAfterConnect;
- break;
-
- case 2: // Listen and accept connection from remote node
- gEpFlags[1] = kDoBindFlag | kDoProtAddrAfterBind | kDoListenFlag |
- kDoAcceptFlag | kDoProtAddrAfterConnect;
- break;
-
- case 3: // Listen and reject connection from remote node
- gEpFlags[1] = kDoBindFlag | kDoProtAddrAfterBind | kDoListenFlag |
- kDoRejectFlag | kDoProtAddrAfterConnect;
- break;
-
- case 4: // Listen and handoff connection from remote node
- gEpFlags[1] = kDoBindFlag | kDoProtAddrAfterBind | kDoListenFlag |
- kDoHandOffFlag | kDoProtAddrAfterConnect;
- break;
-
- case 5: // Connect/Listen/Accept self-send
- gEpFlags[0] = kDoBindFlag | kDoProtAddrAfterBind | kDoConnectFlag |
- kDoSelfSend | kDoProtAddrAfterConnect;
- gEpFlags[1] = kDoBindFlag | kDoProtAddrAfterBind | kDoListenFlag |
- kDoAcceptFlag | kDoSelfSend | kDoProtAddrAfterConnect;
- break;
-
- case 6: // Connect/Listen/Reject self-send
- gEpFlags[0] = kDoBindFlag | kDoProtAddrAfterBind | kDoConnectFlag |
- kDoSelfSend | kDoProtAddrAfterConnect;
- gEpFlags[1] = kDoBindFlag | kDoProtAddrAfterBind | kDoListenFlag |
- kDoRejectFlag | kDoSelfSend | kDoProtAddrAfterConnect;
- break;
-
- case 7: // Connect/Listen/HandOff self-send
- gEpFlags[0] = kDoBindFlag | kDoProtAddrAfterBind | /*kDoConnectFlag | */
- kDoSelfSend | kDoProtAddrAfterConnect;
- gEpFlags[1] = kDoBindFlag | kDoProtAddrAfterBind | kDoListenFlag |
- kDoHandOffFlag | kDoSelfSend | kDoProtAddrAfterConnect;
- break;
- };
-
- //
- // Now get things rolling!
- // The CheckEndpointState looks at an endpoint's current state, and then based
- // on the flags set above, causes the endpoint do do things.
- // This will sit here until the user clicks the mouse.
- //
- while ( !Button() && !quit )
- {
- err = PollEventList();
- if ( err != kOTNoError )
- break;
- for ( epNum = 0 ; epNum < kMaxEndpoints ; epNum++ )
- {
- err = CheckEndpointState(epNum);
- if ( err != kOTNoError )
- break;
- }
- if ( err != kOTNoError )
- break;
- OTIdle();
- }
- while ( Button() && !quit ) // Let go of the dang thing!
- ;
-
- //
- // Wait for everything to shut down
- //
- fprintf(stderr, "Waiting for all endpoints to unbind...\n");
- gDoingTearDown = true;
-
- OTTimeStamp stamp;
-
- OTGetTimeStamp(&stamp);
-
- while ( !Button() )
- {
- err = PollEventList();
- if ( err != kOTNoError )
- break;
- int keepWaiting = false;
-
- for ( epNum = 0 ; epNum < kMaxEndpoints ; epNum++ )
- {
- err = CheckEndpointState(epNum);
- if ( err != kOTNoError )
- break;
- OTResult state = gEp[epNum]->GetEndpointState();
- if ( state > 0 && state != T_UNBND )
- keepWaiting = true;
- }
- if ( !keepWaiting && OTElapsedMilliseconds(&stamp) > 2000 )
- break;
- OTIdle();
- }
-
- } while ( false );
-
- //
- // Clean up all the endpoints we allocated
- //
- for ( epNum = 0 ; epNum < kMaxEndpoints ; epNum++ )
- {
- if ( gEp[epNum] != NULL )
- {
- gEp[epNum]->RemoveNotifier();
- gEp[epNum]->Close();
- if ( err != kOTNoError )
- fprintf(stderr, "ERROR: CloseEndpoint(gEp[%d]) returned %d\n", epNum, err);
- }
- }
- //
- // Clean up any unread event structures
- //
- {
- OTLink* link;
- while ( (link = gEventList.fHead) != NULL )
- {
- TOTEventItem* item = OTGetLinkObject(link, TOTEventItem, fLink);
- gEventList.fHead = link->fNext;
- delete item;
- }
- }
- }
-
- /*******************************************************************************
- ** Initialize Open Transport and call DoTest function
- ********************************************************************************/
-
- main(int, char**)
- {
- InitGraf(&qd.thePort); // initialize quickdraw so we can use regions
-
- fprintf(stderr, "ADSPSample showing usage of ADSP.\n\n");
- //
- // Initialize Open Transport - we're an application, so pass "true"
- //
- InitOpenTransport();
- //
- // Run the test
- //
- DoTest();
- //
- // Close Open Transport.
- // Not strictly necessary since it patches _ExitToShell and will
- // clean us up anyway.
- //
- CloseOpenTransport();
-
- fprintf(stderr, "\n\nDone\n");
-
- return 0;
- };
-
-